package com.le.edu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.le.edu.domain.entity.*;
import com.le.edu.domain.vo.ChapterInfoVO;
import com.le.edu.domain.vo.CommentVO;
import com.le.edu.domain.vo.CourseAndTeacherAndCommentVO;
import com.le.edu.domain.vo.CourseVO;
import com.le.edu.exception.AppException;
import com.le.edu.mapper.*;
import com.le.edu.service.ChapterService;
import com.le.edu.service.CourseService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 17447
 * @description 针对表【t_course(课程)】的数据库操作Service实现
 * @createDate 2024-04-07 23:27:55
 */
@Service
@RequiredArgsConstructor
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    private final ChapterService chapterService;
    private final ChapterMapper chapterMapper;
    private final CourseDescriptionMapper courseDescriptionMapper;
    private final SectionMapper sectionMapper;
    private final CommentMapper commentMapper;
    private final ThreadPoolExecutor executor;


    @Override
    public CourseVO selectCourseAndDescriptionById(Long courseId) {
        return baseMapper.selectCourseAndDescriptionById(courseId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long addCourseVo(CourseVO vo) {
        Course course = BeanUtil.copyProperties(vo, Course.class);
        int insert = baseMapper.insert(course);
        if (insert <= 0) {
            throw new AppException("课程添加失败");
        }

        Long courseId = course.getCourseId();

        CourseDescription build = CourseDescription.builder().courseId(courseId).description(vo.getDescription()).build();
        courseDescriptionMapper.insert(build);
        return courseId;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCourseInfo(CourseVO vo) {
        Course course = BeanUtil.copyProperties(vo, Course.class);
        int insert = baseMapper.updateById(course);
        if (insert <= 0) {
            throw new AppException("课程修改失败");
        }

        CourseDescription build = CourseDescription.builder().courseId(vo.getCourseId()).description(vo.getDescription()).build();
        courseDescriptionMapper.updateById(build);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeCourseAndDescAndChapterByCourseId(Long[] courseIds) {
        List<Long> idsList = Arrays.asList(courseIds);
        //删除课程
        this.removeByIds(idsList);
        //删除描述
        courseDescriptionMapper.deleteBatchIds(idsList);
        //删除章节
        chapterMapper.delete(new LambdaQueryWrapper<Chapter>()
                .in(Chapter::getCourseId, idsList));
        // 删除课时
        sectionMapper.delete(new LambdaQueryWrapper<Section>()
                .in(Section::getCourseId, idsList));
    }

    @Override
    public CourseAndTeacherAndCommentVO CourseAndDespAndTeacherAndChapterAndCommentV2(Long courseId) {
        CourseAndTeacherAndCommentVO courseAndTeacherAndCommentVO = new CourseAndTeacherAndCommentVO();
        //异步查询课程和讲师详细信息
        CompletableFuture<Void> courseFuture = CompletableFuture.runAsync(() -> {
            CourseVO courseVO = baseMapper.selectCourseAndDescriptionById(courseId);
            BeanUtil.copyProperties(courseVO, courseAndTeacherAndCommentVO);
        }, executor);
        // 异步查询章节课时信息
        CompletableFuture<Void> chapterAndSectionFuture = CompletableFuture.runAsync(() -> {
            List<ChapterInfoVO> chapterInfoVOS = chapterService.getChapterAndSectionVoList(courseId);
            courseAndTeacherAndCommentVO.setChapterInfoVOS(chapterInfoVOS);
        }, executor);
        // 异步查询评论
        CompletableFuture<Void> commentFuture = CompletableFuture.runAsync(() -> {
            List<CommentVO> allCommentVO = commentMapper.selectListWhitUser(new QueryWrapper<Comment>()
                    .eq("c.course_id", courseId)
                    .eq("c.del_flag", "0"));
            List<CommentVO> commentTree = allCommentVO.stream().filter(c -> c.getPid().equals(0L))
                    .peek(c -> c.setChildren(getChildren(c, allCommentVO)))
                    .sorted(Comparator.comparing(BaseEntity::getCreateTime))
                    .toList();
            courseAndTeacherAndCommentVO.setCommentVOS(commentTree);
            // 设置总共评论数
            courseAndTeacherAndCommentVO.setCommentCount(allCommentVO.size());
        }, executor);

        CompletableFuture.allOf(courseFuture, chapterAndSectionFuture, commentFuture).join();
        return courseAndTeacherAndCommentVO;
    }

    /**
     * 递归获取评论树
     *
     * @param commentVO
     * @param all
     * @return
     */
    private List<CommentVO> getChildren(CommentVO commentVO, List<CommentVO> all) {
        return all.stream()
                .filter(c -> c.getPid().equals(commentVO.getCommentId()))
                .peek(c -> c.setChildren(getChildren(c, all)))
                .sorted(Comparator.comparing(BaseEntity::getCreateTime))
                .toList();
    }
}




